package com.molichuxing.gateway.bff.user.services.impl;

import com.alibaba.fastjson.JSONObject;
import com.molichuxing.framework.contants.RedisKeyConst;
import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.result.ResponseResult;
import com.molichuxing.framework.utils.*;
import com.molichuxing.gateway.bff.orders.entity.response.ButtonVo;
import com.molichuxing.gateway.bff.orders.entity.response.UserUsedVo;
import com.molichuxing.gateway.bff.user.convertor.Convert;
import com.molichuxing.gateway.bff.user.entity.request.create.ComplaintCreateVo;
import com.molichuxing.gateway.bff.user.entity.request.create.UserCreateVo;
import com.molichuxing.gateway.bff.user.entity.request.modify.UserModifyVo;
import com.molichuxing.gateway.bff.user.entity.response.*;
import com.molichuxing.gateway.bff.user.services.UserBffService;
import com.molichuxing.gateway.contants.OrderConst;
import com.molichuxing.gateway.property.OrderButtonEnum;
import com.molichuxing.gateway.property.UserTypeEnum;
import com.molichuxing.gateway.property.UserVerifyResultEnum;
import com.molichuxing.gateway.utils.DesenseUtil;
import com.molichuxing.gateway.utils.RequestAttrUtil;
import com.molichuxing.gateway.utils.redis.TokenUtil;
import com.molichuxing.services.business.dto.request.create.EsignAccountBizCreateDto;
import com.molichuxing.services.business.dto.request.create.MobileCreateDto;
import com.molichuxing.services.business.dto.request.modify.UserBizModifyDto;
import com.molichuxing.services.business.dto.response.*;
import com.molichuxing.services.business.service.*;
import com.molichuxing.services.contants.OrderStatusConst;
import com.molichuxing.services.infrastructure.dto.request.create.*;
import com.molichuxing.services.infrastructure.dto.response.CarDto;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * 用户服务接口实现类
 * 
 * @author liyg 2019-09-17
 *
 */
@Service("userBffService")
public class UserBffServiceImpl implements UserBffService {

	private final static String ERROR = "error";

	private static final Logger logger = LoggerFactory.getLogger(UserBffServiceImpl.class);

	// 环境
	@Value("${profiles.active}")
	private String active;

	@Value("${app.login.time}")
	private Integer appLoginTime;

	@Value("${auth.is.true}")
	private boolean authIsTrue;
	@Value("${auth.code}")
	private String authCode;
	@Value("${verify.days}")
	private Integer verifyDays;
	// 风控-购车用户年龄
	@Value("${risk.user.age.floor}")
	private Integer ageFloor;
	@Value("${risk.user.age.upper}")
	private Integer ageUpper;
	// 风控-购车用户每日申请上限
	@Value("${risk.apply.upper}")
	private Integer riskApplyUpper;
	@Value("${white.list.id.number}")
	private String whiteListIdNumber;
	
	@Value("${wechat.appid}")
	private String appid;
	@Value("${wechat.appsecret}")
	private String appsecret;
	@Value("${base.url}")
	private String baseUrl;
	@Value("${fico.is.true}")
	private Boolean ficoIsTrue;

	private final static String PHONE = "170,171,165";

	private final static String IDNUMBER = "辽宁,吉林,黑龙江";

	private final static String IDNUMBERNOPASS = "台湾,香港,澳门,国外";

	private final static String USERNAME = "moli";

	@Resource
	private RedisUtil redisUtil;
	@Resource
	private TokenUtil tokenUtil;
	@Resource
	private UserService userService;
	@Resource
	private UserBizService userBizService;
	@Resource
	private RegionService regionService;
	@Resource
	private BlacklistService blacklistService;
	@Resource
	private PhoneRecognitionService phoneRecognitionService;
	@Resource
	private CreditRecognitionService creditRecognitionService;
	@Resource
	private MobileBizService mobileBizService;
	@Resource
	private MessageContentService messageContentService;
	@Resource
	private MessageCenterService messageCenterService;
	@Resource
	private DrivingLicenseService drivingLicenseService;
	@Resource
	private LoginLogAppService loginLogAppService;
	@Resource
	private ComplaintService complaintService;

	@Resource
	private OrderBizService orderBizService;

	@Resource
	private StoreBizService storeBizService;
	
	@Resource
	private SmsBizService smsBizService;
	
	@Resource
	private GuarantorService guarantorService;
	
	@Resource
	private EsignBizService esignBizService;
	
	@Resource
	private FicoCreditInvestigationService ficoCreditInvestigationService;
	
	@Resource
	private UserWhiteService userWhiteService;

	@Resource
	private CarService carService;

	@Resource
	private CarBizService carBizService;

	@Resource
	private VehiclePictureService vehiclePictureService;

	@Resource
	private IovCarService iovCarService;

	@Resource
	private OrderSubscribeBizService orderSubscribeBizService;

	@Resource
	private OrderScheduleService orderScheduleService;
	
	/**
	 *微信token地址
	 */
	private static final String wechatTokenUrl="https://api.weixin.qq.com/cgi-bin/token";
	
	/**
	 *微信Ticke地址
	 */
	private static final String wechatTicketUrl="https://api.weixin.qq.com/cgi-bin/ticket/getticket";
	
	


	/**
	 * 用户登录注册接口
	 * 
	 * @param createVo
	 * @return
	 */
	@Override
	public ResponseResult<UserLoginVo> memberUserLogin(UserCreateVo createVo) {
		// 验证参数
		validateParams(createVo);
		// 登录失败次数key
		String errorNumKey = ERROR + ":" + RedisKeyConst.SMS_USER_CODE_LOGIN + Md5Util.md5Hex(active) + "."
				+ Md5Util.md5Hex(createVo.getPhone());
		String errorNumStr = redisUtil.get(errorNumKey);
		Integer errorNum = errorNumStr == null ? 0 : Integer.valueOf(errorNumStr.trim());
		// 短信验证码key
		String verificationCodeKey = RedisKeyConst.SMS_USER_CODE_LOGIN
				+ Md5Util.md5Hex(active + UserTypeEnum.APP_USER.getValue()) + "." + Md5Util.md5Hex(createVo.getPhone());
		String verificationCodeStr = redisUtil.get(verificationCodeKey);
		verificationCodeStr = verificationCodeStr == null ? "" : verificationCodeStr;
		//验证用户是否在白名单
		if(userWhiteService.getByPhone(createVo.getPhone(), createVo.getVerificationCode(),createVo.getUserSource())) {
			return memberUserLogin(createVo, errorNumKey, errorNum);
		}
		// 万能验证码
		if (authIsTrue && authCode.equals(createVo.getVerificationCode())) {
			return memberUserLogin(createVo, errorNumKey, errorNum);
		}
		// 登录错误次数不大于三次则不用校验图形验证码，否则，则需要校验图形验证码
		if (errorNum < 3) {
			return verificationCode(createVo, verificationCodeStr, errorNumKey, errorNum);
		}
		// 图形验证码key
		String picAuthCodeKey = RedisKeyConst.IMG_USER_CODE_LOGIN + Md5Util.md5Hex(active) + "."
				+ Md5Util.md5Hex(createVo.getPhone());
		String picAuthCodeStr = redisUtil.get(picAuthCodeKey);
		picAuthCodeStr = picAuthCodeStr == null ? "" : picAuthCodeStr;
		return picAuthCode(createVo, verificationCodeStr, picAuthCodeStr, errorNumKey, errorNum);
	}

	/**
	 * 退出系统
	 * 
	 * @param token
	 * @param channel
	 * @return
	 */
	@Override
	public Boolean logOut(String token, String channel) {
		if (OrderSourceEnum.JSAPI.equals(Enum.valueOf(OrderSourceEnum.class, channel.toUpperCase()))) {
			UserVo userVo = tokenUtil.getUserVo(token);
			userService.modifyUserOpenId(null, userVo.getUserId());
		}
		return tokenUtil.logOut(token);
	}

	/**
	 * 验证登录参数
	 * 
	 * @param createVo
	 */
	private void validateParams(UserCreateVo createVo) {
		Assert.notNull(createVo, "参数不能为空");
		validatePhone(createVo.getPhone());
		Assert.notNull(createVo.getUserSource(), "数据来源不能为空");
		if (null == UserSourceEnum.getEnum(createVo.getUserSource())) {
			throw new BizException(1, "非法的数据来源");
		}

		Assert.notNull(createVo.getVerificationCode(), "验证码不能为空");
	}

	/**
	 * 验证手机号
	 * 
	 * @param phone
	 */
	private void validatePhone(String phone) {
		Assert.hasLength(phone, "参数不能为空");
		if (phone.length() != 11 || !phone.startsWith("1")) {
			throw new BizException(400, "手机号格式不正确");
		}
		String[] splitPhone = PHONE.split(",");
		for (String str : splitPhone) {
			if (phone.startsWith(str)) {
				throw new BizException(1, "暂不支持170、171、165号段的手机号");
			}
		}
	}

	/**
	 * 短信验证
	 * 
	 * @param createVo
	 * @param verificationCodeStr
	 * @param errorNumKey
	 * @param errorNum
	 * @return
	 */
	private ResponseResult<UserLoginVo> verificationCode(UserCreateVo createVo, String verificationCodeStr,
			String errorNumKey, Integer errorNum) {
		UserLoginVo vo = new UserLoginVo();
		if (!verificationCodeStr.equals(createVo.getVerificationCode())) {
			errorNum++;
			redisUtil.setex(errorNumKey, errorNum.toString(), appLoginTime);
			vo.setErrorNum(errorNum);
			return new ResponseResult<UserLoginVo>(1, "验证码错误，请重新输入", vo);
		}
		return memberUserLogin(createVo, errorNumKey, errorNum);
	}

	/**
	 * 图形验证和短信验证
	 * 
	 * @param createVo
	 * @param verificationCodeStr
	 * @param picAuthCodeStr
	 * @param errorNumKey
	 * @param errorNum
	 * @return
	 */
	private ResponseResult<UserLoginVo> picAuthCode(UserCreateVo createVo, String verificationCodeStr,
			String picAuthCodeStr, String errorNumKey, Integer errorNum) {
		UserLoginVo vo = new UserLoginVo();
		if (!picAuthCodeStr.equals(createVo.getPicAuthCode())) {
			errorNum++;
			redisUtil.setex(errorNumKey, errorNum.toString(), appLoginTime);
			vo.setErrorNum(errorNum);
			return new ResponseResult<UserLoginVo>(1, "图形验证码错误，请重新输入", vo);
		}
		if (!verificationCodeStr.equals(createVo.getVerificationCode())) {
			errorNum++;
			redisUtil.setex(errorNumKey, errorNum.toString(), appLoginTime);
			vo.setErrorNum(errorNum);
			return new ResponseResult<UserLoginVo>(1, "验证码错误，请重新输入", vo);
		}
		return memberUserLogin(createVo, errorNumKey, errorNum);
	}

	/**
	 * 登录注册
	 * 
	 * @param createVo
	 * @return
	 */
	private ResponseResult<UserLoginVo> memberUserLogin(UserCreateVo createVo, String errorNumKey, Integer errorNum) {
		UserDto user = userService.getUserByPhone(createVo.getPhone());
		if (UserSourceEnum.WECHAT.getValue() == createVo.getUserSource()) {
			String openId = createVo.getOpenId();
			if (StringUtils.isBlank(openId)) {
				throw new BizException(101, "openId不能为空");
			}
			userService.modifyUserOpenId(openId);
		}

		if (null == user || null == user.getId()) {
			return createUserRegister(createVo, errorNumKey, errorNum);
		}
		return modifyUserLogin(user, errorNumKey, errorNum, createVo);
	}

	/**
	 * 注册
	 * 
	 * @param createVo
	 * @param errorNumKey
	 * @return
	 */
	private ResponseResult<UserLoginVo> createUserRegister(UserCreateVo createVo, String errorNumKey,
			Integer errorNum) {
		UserLoginVo vo = new UserLoginVo();
		UserCreateDto createDto = new UserCreateDto();
		// 获取用户名
		String name = getName();
		createDto.setName(name);
		createDto.setPhone(createVo.getPhone());
		createDto.setRegtime(LocalDateTime.now());
		createDto.setSource(createVo.getUserSource());
		createDto.setWeixin(createVo.getOpenId());
		Integer userId = userService.createUser(createDto);
		UserVo userVo = new UserVo();
		BeanUtils.copyProperties(createDto, userVo);
		userVo.setUserId(userId);
		vo.setErrorNum(errorNum);
		vo.setUserVo(userVo);
		String token = null;
		if (UserSourceEnum.WECHAT.getValue() == createVo.getUserSource()) {
			token = tokenUtil.setWechatUserToken(userVo, createVo.getOpenId());
		} else {
			token = tokenUtil.setUserToken(userVo);
		}
		vo.setToken(token);
		//发送短信
		sendNote(userVo);
		redisUtil.del(errorNumKey);
		return new ResponseResult<UserLoginVo>(0, "注册成功", vo);
	}

	/**
	 * 注册成功发送短信
	 * @param userVo
	 */
	private void sendNote(UserVo userVo) {
		JSONObject json=new JSONObject();
	    json.put("name", userVo.getName());
	    try {
	    	smsBizService.sendMessage(userVo.getPhone(), SmsTemplateEnum.NEW_USER_REGISTER.getValue(), json.toJSONString(), null);
		} catch (Exception e) {
			logger.error("新用户注册发送短信失败",e);
		}
	}
	
	/**
	 * 获取默认生成的用户名
	 * 
	 * @return
	 */
	private String getName() {
		String name = RandomCode.randomString(4);
		name = USERNAME + name;
		UserDto user = userService.getUserByName(name);
		if (null == user) {
			return name;
		}
		getName();
		return name;
	}

	/**
	 * 登录
	 * 
	 * @param createVo
	 * @param errorNumKey
	 * @return
	 */
	private ResponseResult<UserLoginVo> modifyUserLogin(UserDto user, String errorNumKey, Integer errorNum,
			UserCreateVo createVo) {
		UserLoginVo vo = new UserLoginVo();
		Integer userId = user.getId();
		if (UserSourceEnum.WECHAT.getValue() == createVo.getUserSource()) {
			userService.modifyUserOpenId(createVo.getOpenId(), userId);
		}
		UserVo userVo = getUserByUserId(userId);
		String token = null;
		if (UserSourceEnum.WECHAT.getValue() == createVo.getUserSource()) {
			token = tokenUtil.setWechatUserToken(userVo, createVo.getOpenId());
		} else {
			token = tokenUtil.setUserToken(userVo);
		}
		redisUtil.del(errorNumKey);
		vo.setToken(token);
		vo.setErrorNum(errorNum);
		vo.setUserVo(userVo);
		createLoginLog(user, createVo);
		return new ResponseResult<UserLoginVo>(0, "登录成功", vo);
	}

	/**
	 * 保存登录日志
	 * 
	 * @param user
	 * @param userVo
	 */
	private void createLoginLog(UserDto user, UserCreateVo userVo) {
		LoginLogCreateDto createDto = new LoginLogCreateDto();
		createDto.setUserId(user.getId());
		createDto.setLoginName(userVo.getPhone());
		createDto.setLoginTerminal(userVo.getUserSource());
		createDto.setLoginIp(userVo.getIpAddr());
		createDto.setLoginDate(LocalDateTime.now());
		// 登录状态 1:正常 2:异常
		createDto.setLoginStatus(1);
		loginLogAppService.create(createDto);
	}

	/**
	 * 获取用户信息
	 * 
	 * @param userId
	 * @return
	 */
	private UserVo getUserByUserId(Integer userId) {
		UserBizDto userBizDto = userBizService.getUser(userId);
		UserVo userVo = Convert.toUserVo(userBizDto);
		if (null == userVo) {
			throw new BizException(101, "不存在该用户信息");
		}
		// 获取省市区信息
		getCity(userBizDto, userVo);
		return userVo;
	}

	/**
	 * 
	 * @param userBizDto
	 * @param userVo
	 */
	private void getCity(UserBizDto userBizDto, UserVo userVo) {
		if (null == userBizDto) {
			return;
		}
		if (null == userBizDto.getRegionId()) {
			return;
		}
		RegionInfoDto city = regionService.getCityNameByAreaId(userVo.getRegionId());
		if (null != city) {
			userVo.setProvinceId(city.getProvinceId());
			userVo.setCityId(city.getCityId());
			userVo.setRegionName(city.getProvinceFullName() + city.getCityFullName() + city.getAreaFullName());
		}
	}

	/**
	 * 根据token获取用户信息
	 * 
	 * @param token
	 * @return
	 */
	@Override
	public UserVo getUserByToken(String token) {
		return tokenUtil.getUser(token);
	}

	/**
	 * 根据openId获取用户信息
	 * 
	 * @return
	 */
	@Override
	public UserVo getUserByOpenId(String openId) {
		try {
			UserBizDto userBizDto = userBizService.getUserByOpenId(openId);
			UserVo userVo = Convert.toUserVo(userBizDto);
			// 获取省市区信息
			getCity(userBizDto, userVo);
			return userVo;
		} catch (Exception e) {
			logger.error("服务异常：", e);
			return null;
		}
	}

	/**
	 * 修改用户信息
	 * 
	 * @param modifyVo
	 * @param token
	 * @return
	 */
	@Override
	public ResponseResult<String> modifyUser(UserModifyVo modifyVo, String token) {

		UserVo userVo = tokenUtil.getUserVo(token);
		// 验证参数
		validateParams(modifyVo, userVo);

		String idNumber = modifyVo.getIdNumber();
		// 验证身份证
		validateIdNumber(idNumber);

		BlacklistDto blacklist = blacklistService.getBlacklist(userVo.getPhone());
		if (null != blacklist) {
			throw new BizException(1, "抱歉，您未通过征信验证");
		}
		
		//验证用户是否下过单
		orderVerify(userVo,modifyVo);

		Integer userId = userVo.getUserId();
		// Boolean flagPhone =
		// phoneRecognitionService.getVerifyResult(userVo.getUserId(),
		// DateUtil.getNDays(-verifyDays));
		Boolean flagCredit = creditRecognitionService.getVerifyResult(userVo.getUserId(),
				DateUtil.getNDays(-verifyDays));
		// if(flagPhone && flagCredit) {
		// modifyUser(modifyVo,userId,token);
		// return new ResponseResult<String>().success();
		// }
		if (flagCredit) {
			modifyUser(modifyVo, userId, token);
			return new ResponseResult<String>().success();
		}

		MobileCreateDto createDto = new MobileCreateDto();
		createDto.setIdNumber(modifyVo.getIdNumber());
		createDto.setRealName(modifyVo.getRealName());
		createDto.setPhone(modifyVo.getPhone());
		// if(!flagPhone) {
		// return getMoblie(createDto,modifyVo,flagCredit,userId,token);
		// }

		return getCredit(createDto, modifyVo, userId, token);
	}

	/**
	 * 验证用户是否下过单
	 * @param userVo
	 * @param modifyVo
	 */
	private void orderVerify(UserVo userVo,UserModifyVo modifyVo) {
		Integer guarantorId =null;
		//查询担保人信息
		GuarantorDto guarantorDto = guarantorService.getByIdNumber(modifyVo.getIdNumber());
		if(null != guarantorDto) {
			guarantorId=guarantorDto.getId();
		}
		OrderVerifyBizDto orderVerify = orderBizService.orderVerify(userVo.getUserId(), guarantorId);
		if(null == orderVerify) {
			throw new BizException(1, "抱歉，您未通过征信验证");
		}
		if(null == orderVerify.getIsOrder() || orderVerify.getIsOrder()) {
			throw new BizException(1, "抱歉，您名下已有订单尚未完成，暂时无法下单");
		}
		if(null == orderVerify.getIsGuarantorOrder() || orderVerify.getIsGuarantorOrder()) {
			throw new BizException(1, "抱歉，您正在为他人提供担保，暂时无法下单");
		}
	}
	
	/**
	 * 验证三要素参数
	 * 
	 */
	private void validateParams(UserModifyVo modifyVo, UserVo userVo) {
		Assert.notNull(modifyVo, "参数不能为空");
		validatePhone(modifyVo.getPhone());
		if (!userVo.getPhone().equals(modifyVo.getPhone())) {
			throw new BizException(400, "手机号码与当前登录手机号码不一致");
		}
		Assert.hasLength(modifyVo.getRealName(), "真实姓名不能为空");
		if (StringUtils.isNoneBlank(userVo.getRealName())) {
			if (!userVo.getRealName().equals(modifyVo.getRealName())) {
				throw new BizException(400, "姓名与当前登录人信息不一致");
			}
		}
		String idNumber = modifyVo.getIdNumber();
		if (!CheckIdCardUtil.validateCard(idNumber)) {
			throw new BizException(400, "请填写正确的身份证号");
		}
		if (StringUtils.isNoneBlank(userVo.getIdNumber())) {
			if (!userVo.getIdNumber().equals(idNumber)) {
				throw new BizException(400, "身份证号与当前登录人信息不一致");
			}
		}

		Assert.notNull(modifyVo.getRegionId(), "地址不能为空");
		Assert.hasLength(modifyVo.getAddress(), "地址不能为空");
	}

	/**
	 * 验证身份证
	 * 
	 * @param idNumber
	 */
	private void validateIdNumber(String idNumber) {
		String[] splitWhiteList = whiteListIdNumber.split(",");
		for (String whiteList : splitWhiteList) {
			if (whiteList.equals(idNumber)) {
				return;
			}
		}

		String province = CheckIdCardUtil.getProvinceByIdCard(idNumber);
		String[] idNumberNoPass = IDNUMBERNOPASS.split(",");
		for (String str : idNumberNoPass) {
			if (str.equals(province)) {
				throw new BizException(1, "抱歉，暂不受理港澳台同胞及外籍户籍人群");
			}
		}

		String[] splitNumber = IDNUMBER.split(",");
		for (String str : splitNumber) {
			if (str.equals(province)) {
				throw new BizException(1, "很抱歉，您不符合签约条件");
			}
		}
	}

	/**
	 * 获取三要素信息
	 * 
	 * @param createDto
	 * @param flagCredit
	 * @param userId
	 * @return
	 */
	private ResponseResult<String> getMoblie(MobileCreateDto createDto, UserModifyVo modifyVo, Boolean flagCredit,
			Integer userId, String token) {
		ResponseResult<String> response = mobileBizService.getMoblie(createDto);
		Integer verifyResult = VerifyResultEnum.PASS.getValue();
		if (!response.getCode().equals(0)) {
			// 保存三要素验证信息
			verifyResult = VerifyResultEnum.NO_PASS.getValue();
			savePhoneRecognitionService(createDto, verifyResult, userId);
			return response;
		}
		// 保存三要素验证信息
		savePhoneRecognitionService(createDto, verifyResult, userId);
		// 验证征信本地数据
		if (flagCredit) {
			modifyUser(modifyVo, userId, token);
			return response;
		}
		return getCredit(createDto, modifyVo, userId, token);
	}

	/**
	 * 获取征信信息
	 * 
	 * @param createDto
	 * @param modifyVo
	 * @param userId
	 * @param token
	 * @return
	 */
	private ResponseResult<String> getCredit(MobileCreateDto createDto, UserModifyVo modifyVo, Integer userId,
			String token) {
		ResponseResult<String> respone =null;
		CreditDto creditDto = null;
		Integer verifySource = null; 
		if(ficoIsTrue) {
			respone = ficoCreditInvestigationService.creditInvestigation(createDto);
			verifySource = CreditVerifySourceEnum.FICO.getValue();
		}else {
			ResponseResult<CreditDto> creditResponse = mobileBizService.getCredit(createDto);
			creditDto = creditResponse.getData();
			verifySource = CreditVerifySourceEnum.PY.getValue();
			if(creditResponse.getCode().equals(0)) {
				respone=new ResponseResult<String>().success();
			}else {
				respone=new ResponseResult<String>().error(creditResponse.getCode(), creditResponse.getMessage());
			}
		}
		Integer verifyResult = VerifyResultEnum.PASS.getValue();
		if (!respone.getCode().equals(0)) {
			verifyResult = VerifyResultEnum.NO_PASS.getValue();
			saveCreditRecognition(createDto, verifyResult, userId,creditDto,verifySource);
			return respone;
		}
		saveCreditRecognition(createDto, verifyResult, userId,creditDto,verifySource);
		modifyUser(modifyVo, userId, token);
		return respone;
	}

	/**
	 * 保存征信验证结果
	 * 
	 * @param mobileCreateDto
	 * @param verifyResult
	 * @param userId
	 * @param creditDto
	 * @param verifySource
	 */
	private void saveCreditRecognition(MobileCreateDto mobileCreateDto, Integer verifyResult, Integer userId,CreditDto creditDto,Integer verifySource) {
		CreditRecognitionCreateDto createDto = new CreditRecognitionCreateDto();
		createDto.setUserId(userId);
		createDto.setPhone(mobileCreateDto.getPhone());
		createDto.setVerifyResult(verifyResult);
		createDto.setVerifyTime(LocalDateTime.now());
		if(null != creditDto) {
			createDto.setRiskScore(creditDto.getRiskScore());
			createDto.setScore(creditDto.getScore());
		}
		createDto.setVerifySource(verifySource);
		creditRecognitionService.create(createDto);
	}

	/**
	 * 保存三要素验证结果
	 * 
	 * @param mobileCreateDto
	 * @param verifyResult
	 * @param userId
	 */
	private void savePhoneRecognitionService(MobileCreateDto mobileCreateDto, Integer verifyResult, Integer userId) {
		PhoneRecognitionCreateDto createDto = new PhoneRecognitionCreateDto();
		createDto.setUserId(userId);
		createDto.setPhone(mobileCreateDto.getPhone());
		createDto.setVerifyResult(verifyResult);
		createDto.setVerifyTime(LocalDateTime.now());
		phoneRecognitionService.create(createDto);
	}

	/**
	 * 保存用户信息
	 * 
	 * @param modifyVo
	 * @param userId
	 * @param token
	 */
	private void modifyUser(UserModifyVo modifyVo, Integer userId, String token) {
		UserBizModifyDto modifyDto = new UserBizModifyDto();
		modifyDto.setId(userId);
		modifyDto.setRealName(modifyVo.getRealName());
		modifyDto.setIdNumber(modifyVo.getIdNumber());
		modifyDto.setAddress(modifyVo.getAddress());
		modifyDto.setRegionId(modifyVo.getRegionId());
		// modifyDto.setEmail(modifyVo.get));
		// 修改用户信息
		userBizService.modifyUser(modifyDto);
		UserVo user = getUserByUserId(userId);
		tokenUtil.modifyUserToken(user);
		tokenUtil.modifyWechatUserToken(user);
		//生成用户印章信息
		createEsignAccount(user.getIdNumber(),user.getRealName(),user.getPhone());
	}

	/**
	 * 生成用户印章信息
	 * @param idNumber
	 * @param realName
	 * @param phone
	 */
	private void createEsignAccount(String idNumber,String realName,String phone) {
		EsignAccountBizCreateDto dto = new EsignAccountBizCreateDto();
		dto.setIdNo(idNumber);
		dto.setMobile(phone);
		dto.setName(realName);
		try {
			esignBizService.createEsignAccount(dto);
		} catch (Exception e) {
			logger.error("用生成印章信息失败",e);
		}
	}
	
	/**
	 * 修改用户信息
	 * 
	 * @param modifyVo
	 * @param token
	 * @return
	 */
	@Override
	public Boolean modifyUserAddress(UserModifyVo modifyVo, String token) {
		Assert.notNull(modifyVo, "参数不能为空");
		String address = modifyVo.getAddress();
		Assert.hasLength(address, "地址不能为空");
		Integer regionId = modifyVo.getRegionId();
		Assert.notNull(regionId, "地址不能为空");
		UserVo userVo = tokenUtil.getUserVo(token);
		UserBizModifyDto modifyDto = new UserBizModifyDto();
		Integer userId = userVo.getUserId();
		modifyDto.setId(userId);
		modifyDto.setRegionId(regionId);
		modifyDto.setAddress(address);
		Boolean flag = userBizService.modifyUserAddress(modifyDto);
		UserVo user = getUserByUserId(userId);
		tokenUtil.modifyUserToken(user);
		tokenUtil.modifyWechatUserToken(user);
		return flag;
	}

	@Override
	public Paged<MessageCenterVo> getMessageCenterPage(Integer pageNum, Integer pageSize) throws Exception {
		Paged<MessageCenterVo> accidentPagedVoPaged = new Paged<>(null, 0, pageSize);
		// 获取当前登录的用户id
		Integer userId = RequestAttrUtil.getCurrentUserId();
		if (null == userId) {
			throw new Exception("用户未登录");
		}
		Map<String, Object> map = new HashMap<>();
		map.put("userId", userId);

		// 查询消息主体
		Paged<MessageCenterDto> messageCenterDtoPage = messageCenterService.getMessageCenterPage(map, pageNum,
				pageSize);
		if (null == messageCenterDtoPage || null == messageCenterDtoPage.getList()
				|| messageCenterDtoPage.getList().size() <= 0) {
			return accidentPagedVoPaged;
		}
		BeanUtils.copyProperties(messageCenterDtoPage, accidentPagedVoPaged);
		List<MessageCenterVo> messageCenterVoList = new ArrayList<>();
		MessageCenterVo messageCenterVo = null;
		List<MessageContentVo> messageContentVoList = null;
		MessageContentVo messageContentVo = null;

		for (MessageCenterDto messageCenterDto : messageCenterDtoPage.getList()) {
			messageCenterVo = new MessageCenterVo();
			BeanUtils.copyProperties(messageCenterDto, messageCenterVo);
			messageCenterVo.setStatusStr(MessageCenterStatusEnum.getName(messageCenterDto.getStatus()));
			messageCenterVo.setTypeStr(MessageCenterTypeEnum.getName(messageCenterDto.getType()));
			// 查询消息内容
			List<MessageContentDto> messageContentDtoList = messageContentService
					.getMessageContentByCenterId(messageCenterDto.getId());
			if (null != messageContentDtoList && messageContentDtoList.size() > 0) {
				messageContentVoList = new ArrayList<>();
				for (MessageContentDto messageContentDto : messageContentDtoList) {
					messageContentVo = new MessageContentVo();
					BeanUtils.copyProperties(messageContentDto, messageContentVo);
					messageContentVoList.add(messageContentVo);
				}
				messageCenterVo.setMessageContentVoList(messageContentVoList);
			}
			messageCenterVoList.add(messageCenterVo);
		}
		accidentPagedVoPaged.setList(messageCenterVoList);
		// 将该用户所有消息置为已读
		messageCenterService.modifyStatusByUserId(userId);
		return accidentPagedVoPaged;
	}

	@Override
	public Integer getUnreadCount() throws Exception {
		// 获取当前登录的用户id
		Integer userId = RequestAttrUtil.getCurrentUserId();
		return null == userId ? 0 : messageCenterService.getUnreadCount(userId);
	}

	/**
	 * 获取用户驾驶证信息
	 * 
	 * @return
	 */
	@Override
	public DrivingLicenseVo getDrivingLicense() {
		UserVo userVo = RequestAttrUtil.getCurrentUser();
		DrivingLicenseDto drivingLicense = drivingLicenseService.getDrivingLicense(userVo.getUserId());
		if (null == drivingLicense) {
			return null;
		}
		DrivingLicenseVo vo = new DrivingLicenseVo();
		BeanUtils.copyProperties(drivingLicense, vo);
		if (DrivingLicenseStatusEnum.VERIFY_FAILURE.getValue() == drivingLicense.getStatus()
				&& drivingLicense.getDataSource() == DrivingLicenseDataSourceEnum.LABOUR_JUDGE.getValue()) {

			if (!userVo.getRealName().equals(drivingLicense.getName())) {
				vo.setRejectReason("驾驶证姓名与身份姓名不一致");
			} else if (!userVo.getIdNumber().equals(drivingLicense.getLicenseCode())) {
				vo.setRejectReason("驾驶证号与身份证号不一致");
			} else if (!DrivingLicenseUtil.verificationDriverLicense(drivingLicense.getModel())) {
				vo.setRejectReason("准驾车型未满足要求");
			}

			if(null != drivingLicense.getVerifyStatus()) {
				if (DrivingLicenseVerifyStatusEnum.REJECT.getValue() == drivingLicense.getVerifyStatus()) {
					String rejectReason = drivingLicense.getRejectReason();
					if (StringUtils.isNoneBlank(rejectReason)) {
						vo.setRejectReason(rejectReason);
					}
				}
			}

		}
		String licenseCode = drivingLicense.getLicenseCode();
		if(StringUtils.isNoneBlank(licenseCode)) {
			if(licenseCode.length() >= 15) {
				vo.setLicenseCode(DesenseUtil.toConceal(licenseCode));
			}
		}
		return vo;
	}

	/**
	 * 获取用户投诉信息接口
	 * 
	 * @return
	 */
	@Override
	public ComplaintVo getComplaintVo() {
		UserVo userVo = RequestAttrUtil.getCurrentUser();
		ComplaintDto complaint = complaintService.getComplaintByUserId(userVo.getUserId());
		ComplaintVo vo = null;
		if (null != complaint) {
			vo = new ComplaintVo();
			vo.setContent(complaint.getContent());
			vo.setStatus(complaint.getStatus());
			vo.setSubmitTime(complaint.getSubmitTime());
		}
		return vo;
	}

	/**
	 * 提交用户投诉信息
	 * 
	 * @param createVo
	 * @return
	 */
	@Override
	public Boolean createComplaint(ComplaintCreateVo createVo) {
		UserVo userVo = RequestAttrUtil.getCurrentUser();
		ComplaintCreateDto createDto = new ComplaintCreateDto();
		createDto.setType(1);
		createDto.setUserId(userVo.getUserId());
		createDto.setSource(createVo.getSource());
		createDto.setContent(createVo.getContent());
		createDto.setSubmitTime(LocalDateTime.now());
		createDto.setStatus(ComplaintStatusEnum.UNTREATED.getValue());
		return complaintService.createComplaint(createDto);
	}

	/**
	 * 用户检验（黑名单、是否有生效中订单）
	 * 
	 * @param user
	 * @return
	 * @throws Exception
	 */
	@Override
	public UserVerifyVo getVerify(UserVo user, String cpu) throws Exception {
		UserVerifyVo result = new UserVerifyVo();
		// 查询是否黑名单用户
		BlacklistDto blacklistDto = blacklistService.getBlacklist(user.getPhone());
		if (blacklistDto != null) {
			result.setIsBlacklist(true);
		} else {
			result.setIsBlacklist(false);
		}
		// 获取所有用户正常订单
		List<OrderMemberBizDto> orderMemberBizDtos = orderBizService.getNormalOrderByUser(user.getUserId());
		if (orderMemberBizDtos == null || orderMemberBizDtos.isEmpty()) {
			result.setIsOrders(false);
			if (result.getIsBlacklist()) {
				result.setResult(UserVerifyResultEnum.TERMINATED.getValue());
				result.setResultExplain("抱歉！您未通过身份识别");
			} else {
				result.setResult(UserVerifyResultEnum.GO_GOODS.getValue());
			}
			return result;
		}
		OrderMemberBizDto orderMemberBizDto = orderMemberBizDtos.get(0);
		result.setOrderCode(orderMemberBizDto.getOrderCode());
		if (OrderTypeEnum.EXCLUSIVEL.equals(orderMemberBizDto.getType())) {
			// 专属订单
			OrderExclusivelBizDto orderBizDto = (OrderExclusivelBizDto) orderMemberBizDto;
			if (OrderExclusivelStatusEnum.TRADE_FINISH.equals(orderBizDto.getOrderStatus())
					|| OrderExclusivelStatusEnum.RENEGE_FINISH.equals(orderBizDto.getOrderStatus())) {
				// 交易结束、退租已完成订单，不显示
				result.setIsOrders(false);
				if (result.getIsBlacklist()) {
					result.setResult(UserVerifyResultEnum.TERMINATED.getValue());
					result.setResultExplain("抱歉！您未通过身份识别");
				} else {
					result.setResult(UserVerifyResultEnum.GO_GOODS.getValue());
				}
			} else if (OrderExclusivelStatusEnum.TRADE_UNPAID.equals(orderBizDto.getOrderStatus())) {
				// 待提车订单
				if (result.getIsBlacklist()) {
					result.setIsOrders(false);
					result.setResult(UserVerifyResultEnum.TERMINATED.getValue());
					result.setResultExplain("抱歉！您未通过身份识别");
				} else {
					result.setIsOrders(true);
					result.setResult(UserVerifyResultEnum.GO_ORDER.getValue());
				}
			} else if (OrderExclusivelStatusEnum.TRADE_UNDELIVERY.equals(orderBizDto.getOrderStatus())) {
				// 待提车订单
				if (result.getIsBlacklist()) {
					result.setIsOrders(false);
					result.setResult(UserVerifyResultEnum.TERMINATED.getValue());
					result.setResultExplain("抱歉！您未通过身份识别");
				} else {
					result.setIsOrders(true);
					// 根据大屏cpu号查询绑定门店信息
					StoreBaseBizDto aioStore = storeBizService.getStoreBaseByCpu(cpu);
					if (aioStore.getStoreId().equals(orderBizDto.getPlaceStoreId())) {
						// 下单门店，提车
						result.setResult(UserVerifyResultEnum.GO_DELIVERY.getValue());
					} else {
						result.setResult(UserVerifyResultEnum.GO_ORDER.getValue());
					}
				}
			} else {
				result.setIsOrders(true);
				result.setResult(UserVerifyResultEnum.GO_ORDER.getValue());
			}
		} else if (OrderTypeEnum.SUBSCRIBE.equals(orderMemberBizDto.getType())) {
			// 订阅订单
			OrderSubscribeBizDto orderBizDto = (OrderSubscribeBizDto) orderMemberBizDto;
			if (OrderSubscribeStatusEnum.TRADE_FINISH.equals(orderBizDto.getOrderStatus())
					|| OrderSubscribeStatusEnum.RETURN_FINISH.equals(orderBizDto.getOrderStatus())) {
				// 交易结束、退租已完成、还车已完成订单，不显示
				result.setIsOrders(false);
				if (result.getIsBlacklist()) {
					result.setResult(UserVerifyResultEnum.TERMINATED.getValue());
					result.setResultExplain("抱歉！您未通过身份识别");
				} else {
					result.setResult(UserVerifyResultEnum.GO_GOODS.getValue());
				}
			} else if (OrderSubscribeStatusEnum.TRADE_UNPAID.equals(orderBizDto.getOrderStatus())) {
				// 待付款订单
				if (result.getIsBlacklist()) {
					result.setIsOrders(false);
					result.setResult(UserVerifyResultEnum.TERMINATED.getValue());
					result.setResultExplain("抱歉！您未通过身份识别");
				} else {
					result.setIsOrders(true);
					result.setResult(UserVerifyResultEnum.GO_ORDER.getValue());
				}
			} else if (OrderSubscribeStatusEnum.TRADE_UNDELIVERY.equals(orderBizDto.getOrderStatus())) {
				// 待提车订单
				if (result.getIsBlacklist()) {
					result.setIsOrders(false);
					result.setResult(UserVerifyResultEnum.TERMINATED.getValue());
					result.setResultExplain("抱歉！您未通过身份识别");
				} else {
					result.setIsOrders(true);
					// 根据大屏cpu号查询绑定门店信息
					StoreBaseBizDto aioStore = storeBizService.getStoreBaseByCpu(cpu);
					if (aioStore.getStoreId().equals(orderBizDto.getPlaceStoreId())) {
						// 下单门店，提车
						result.setResult(UserVerifyResultEnum.GO_DELIVERY.getValue());
					} else {
						result.setResult(UserVerifyResultEnum.GO_ORDER.getValue());
					}
				}
			} else {
				result.setIsOrders(true);
				result.setResult(UserVerifyResultEnum.GO_ORDER.getValue());
			}
		} else {
			result.setIsOrders(false);
			if (result.getIsBlacklist()) {
				result.setResult(UserVerifyResultEnum.TERMINATED.getValue());
				result.setResultExplain("抱歉！您未通过身份识别");
			} else {
				result.setResult(UserVerifyResultEnum.GO_GOODS.getValue());
			}
		}

		return result;
	}
	
	/**
	 * 获取微信签名
	 * @return
	 */
	@Override
	public WechatConfigVo getWechatConfig() {
		String wechatToken = getWechatToken();
		if(null == wechatToken) {
			throw new BizException("获取微信token异常");
		}
		String ticket = getTicket(wechatToken);
		if(null == ticket) {
			throw new BizException("获取微信ticket异常");
		}
		//参与签名的字段包括noncestr（随机字符串）
		String noncestr = "Wm3WZYTPz0wzccnW";
		Long timestamp=Long.valueOf(RandomCode.randomNumber(10));
		String str="jsapi_ticket="+ticket+"&"+"noncestr="+noncestr+"&"+"timestamp="+timestamp+"&"+"url="+baseUrl+"/moli/home";
		String sha1 = SHAUtils.SHA1(str);
		WechatConfigVo vo =new WechatConfigVo();
        vo.setAppId(appid);
        vo.setNonceStr(noncestr);
        vo.setTimestamp(timestamp+"");
        vo.setSignature(sha1);
		return vo;
	}

	/**
	 * 获取微信Ticket
	 * @param wechatToken
	 * @return
	 */
	private String getTicket(String wechatToken) {
		
		String ticketKey = RedisKeyConst.WECHAT_TICKET_KEY;
		String ticket = null ;
		try {
			ticket = redisUtil.get(ticketKey);
			if(StringUtils.isNoneBlank(ticket)) {
				return ticket;
			}
		} catch (Exception e) {
			logger.error("redis获取微信Ticket异常：",e);
		}
		
		Map<String,String> map =new HashMap<>(3);
		map.put("access_token", wechatToken);
		map.put("type", "jsapi");
		try {
			String json = HttpClientUtil.doGet(wechatTicketUrl, map);
			logger.info("获取微信Ticket出参："+json);
			if(StringUtils.isNoneBlank(json)) {
				JSONObject parseObject = JSONObject.parseObject(json);
				Object object = parseObject.get("ticket");
				if(null != object) {
					ticket = object.toString();
					redisUtil.setex(ticketKey, ticket, 3600);
				}
			}
			return ticket;
		} catch (Exception e) {
			logger.error("获取微信Ticket异常：",e);
			return null;
		}
		
	}
	
	/**
	 * 获取微信token
	 * @return
	 */
	private String getWechatToken() {
		String tokenKey = RedisKeyConst.WECHAT_TOKEN_KEY;
		String wechatToken=null;
		try {
			wechatToken = redisUtil.get(tokenKey);
			if(StringUtils.isNoneBlank(wechatToken)) {
				return wechatToken;
			}
		} catch (Exception e) {
			logger.error("redis获取微信token异常：",e);
		}
		
		Map<String,String> map =new HashMap<>(3);
		map.put("grant_type", "client_credential");
		map.put("appid", appid);
		map.put("secret", appsecret);
		try {
			String json = HttpClientUtil.doGet(wechatTokenUrl, map);
			logger.info("获取微信token出参："+json);
			if(StringUtils.isNoneBlank(json)) {
				JSONObject parseObject = JSONObject.parseObject(json);
				Object object = parseObject.get("access_token");
				if(null != object) {
					wechatToken = object.toString();
					redisUtil.setex(tokenKey, wechatToken, 3600);
				}
			}
			return wechatToken;
		} catch (Exception e) {
			logger.error("获取微信token异常：",e);
			return null;
		}
	}

	/**
	 * 修改用户为下单用户
	 * 
	 * @param userId
	 *            用户id
	 * @return
	 */
	@Async
	@Override
	public Boolean modifyOrderUser(Integer userId) {
		return userService.modifyUserIsOrder(true, userId);
	}

	@Override
	public Boolean verifyUserToIndex(Integer userId) {
		return orderBizService.getHasPageHomeOrderByUser(userId);
	}

	@Override
	public List<UserHomeMyCarVo> getHomeMyCar(Integer userId, String channel) {
		List<UserHomeMyCarVo> result = null;
		List<OrderMemberBizDto> orderMemberBizDtoList = orderBizService.getNormalOrderByUser(userId);
		if((null == orderMemberBizDtoList)||(orderMemberBizDtoList.size() == 0)) {
			return null;
		}
		result = new ArrayList<>();
		for(OrderMemberBizDto orderMemberBizDto : orderMemberBizDtoList) {
			if(null == orderMemberBizDto.getCarId()||0 >= orderMemberBizDto.getCarId()) {
				continue;
			}
			UserHomeMyCarVo userHomeMyCarVo = new UserHomeMyCarVo();
			if(orderMemberBizDto.getType() == OrderTypeEnum.SUBSCRIBE){
				OrderSubscribeBizDto orderSubscribeBizDto =  (OrderSubscribeBizDto)orderMemberBizDto;
				if(orderSubscribeBizDto.getOrderStatus() != OrderSubscribeStatusEnum.TRADE_USE) {
					continue;
				}
				OrderSubscribeDetailsBizDto orderSubscribeDetailsBizDto = orderSubscribeBizService.getOrderSubscribeDetails(orderMemberBizDto.getOrderCode());
				CarDetailBizDto carDetailBizDto = null;
				if (orderSubscribeDetailsBizDto.getCarId() != null
						&& !OrderSubscribeStatusEnum.TRADE_UNPAID.equals(orderSubscribeDetailsBizDto.getOrderStatus())) {
					carDetailBizDto = carBizService.getCarDetail(orderSubscribeDetailsBizDto.getCarId());
				}
				userHomeMyCarVo.setUsed(userUsed(orderSubscribeDetailsBizDto,carDetailBizDto));
				userHomeMyCarVo.setOrderStatus(orderSubscribeBizDto.getOrderStatus().getValue());
				userHomeMyCarVo.setOrderStatusStr(orderSubscribeBizDto.getOrderStatus().getName());
			}else if(orderMemberBizDto.getType() == OrderTypeEnum.EXCLUSIVEL){
				OrderExclusivelBizDto orderExclusivelBizDto =  (OrderExclusivelBizDto)orderMemberBizDto;
				if(orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.TRADE_UNPAID||
						orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.TRADE_CANCELED||
						orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.TRADE_UNAUDIT||
						orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.TRADE_UNDELIVERY||
						orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.TRADE_REJECTED||
						orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.TRADE_REFUND||
						orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.TRADE_FINISH||
						orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.TRADE_CREDIT_UNAUDIT||
						orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.TRADE_PASS||
						orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.RENEGE_FINISH) {
					continue;
				}
				userHomeMyCarVo.setIsOverDue(orderScheduleService.getIsOverdue(orderMemberBizDto.getOrderCode()));
				userHomeMyCarVo.setOrderStatus(orderExclusivelBizDto.getOrderStatus().getValue());
				userHomeMyCarVo.setOrderStatusStr(orderExclusivelBizDto.getOrderStatus().getName());
			}
			userHomeMyCarVo.setPayType(PaymentCostTypeEnum.RENEGE.getValue());
			userHomeMyCarVo.setOrderCode(orderMemberBizDto.getOrderCode());
			userHomeMyCarVo.setOrderId(orderMemberBizDto.getId());
			userHomeMyCarVo.setOrderType(orderMemberBizDto.getType().getValue());
			CarDto carDto = carService.getCarById(orderMemberBizDto.getCarId());
			if(null != carDto) {
				UserHomeMyCarDetailVo carDetail = new UserHomeMyCarDetailVo();
				List<VehiclePictureDto> pictureList = vehiclePictureService.getVehiclePictureByVehicleId(carDto.getVehicleId());
				for(VehiclePictureDto vehiclePictureDto : pictureList) {
					if(vehiclePictureDto.getIsWhiteBg() && 1 == vehiclePictureDto.getPicDetailType()) {
						carDetail.setVehicleImg(vehiclePictureDto.getServerUrl());
						break;
					}
				}
				carDetail.setCarId(carDto.getId());
				carDetail.setLicencePlate(carDto.getLicencePlate());
				carDetail.setOds(iovCarService.getCurrentMileage(carDto.getVin()));
				//获取电量
				Map<String, Byte> socMap = iovCarService.getSoc(Arrays.asList(carDto.getVin()));
				if((null != socMap)&&(null != socMap.get(carDto.getVin()))) {
					carDetail.setElectricQuantity(socMap.get(carDto.getVin())+"%");
				}
				userHomeMyCarVo.setCarDetail(carDetail);
			}
			userHomeMyCarVo.setButtons(mobileButton(orderMemberBizDto, channel));
			result.add(userHomeMyCarVo);
		}
		return result;
	}

	private List<ButtonVo> mobileButton(OrderMemberBizDto orderMemberBizDto, String channel){
		List<ButtonVo> result = new ArrayList<>();
		//合同
		result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.CONTRACT_INDEX_PAGE));
		OrderSourceEnum valueOf = Enum.valueOf(OrderSourceEnum.class, channel.toUpperCase());
		if ((null != valueOf)&&(valueOf == OrderSourceEnum.ANDROID||valueOf == OrderSourceEnum.IOS)) {
			//发票
			result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.INVOICE));
			result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.MY_VIOLATION));
			result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.ACCIDENT_EPORTING));
			result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.MY_MAINTENANCE));
		}
		if(orderMemberBizDto.getType() == OrderTypeEnum.EXCLUSIVEL) {
			OrderExclusivelBizDto orderExclusivelBizDto = (OrderExclusivelBizDto) orderMemberBizDto;
			if (orderExclusivelBizDto.getPaymentMethod() == OrderPaymentMethodEnum.INSTALLMENT) {
				result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.REPAYMENT_DETAILS));
			}
			if (orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.RENEGE_REFUND) {
				if (OrderRenegeCostTypeEnum.DISBURSE.equals(orderExclusivelBizDto.getRenege().getCostType())) {
					result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.RESCISSION_AGREEMENT));
				} else {
					result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.REFUND_RENT));
				}
			}
			if (orderExclusivelBizDto.getOrderStatus() == OrderExclusivelStatusEnum.RENEGE_UNPAID) {
				if (orderExclusivelBizDto.getCarId() != null && orderExclusivelBizDto.getCarId() > 0 && OrderRenegeCostTypeEnum.INCOME.equals(orderExclusivelBizDto.getRenege().getCostType())) {
					result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.REFUND_RENT));
				}
			}
		}
		if(orderMemberBizDto.getType() == OrderTypeEnum.SUBSCRIBE){
			OrderSubscribeBizDto orderSubscribeBizDto =  (OrderSubscribeBizDto)orderMemberBizDto;
			result = reletButton(orderSubscribeBizDto,result);
		}
		return result;
	}



	/**
	 * 加购、续订button逻辑
	 *
	 * @param result
	 * @return
	 */
	private List<ButtonVo> reletButton(OrderSubscribeBizDto subscribeBizDto, List<ButtonVo> result) {
		// 最迟还车时间
		LocalDateTime leaseExpire = LocalDateTime.parse(subscribeBizDto.getLeaseExpire().toString() + " 18:00:00",
				DateUtil.LOCAL_DATE_TIME);
		// 判断是否超时
		if (LocalDateTime.now().plusMinutes(10).isAfter(leaseExpire)) {
			// 超时
			return result;
		}
		// 查询里程
		CarDetailBizDto carDetailBizDto = carBizService.getCarDetail(subscribeBizDto.getCarId());
		Integer currentMileage = iovCarService.getCurrentMileage(carDetailBizDto.getVin());
		if (currentMileage == null) {
			// 里程异常
			logger.error("[reletButton]查询里程信息异常");
			return result;
		}
		// 计算超里程数
		Integer beyondMileage = currentMileage - subscribeBizDto.getWarningMileage();
		if (beyondMileage < 0) {
			if (!subscribeBizDto.getIsHaveSuborder()) {
				// 已存在续订订单，则不可再次续订
				result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.RENEW_INDEX_PAGE));
			}
			result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.PURCHASED_INDEX_PAGE));
		} else if (beyondMileage >= 0 && beyondMileage <= 30) {
			result.add(com.molichuxing.gateway.bff.orders.convertor.Convert.toButton(OrderButtonEnum.PURCHASED_INDEX_PAGE));
		}
		return result;
	}

	@SuppressWarnings("unused")
	private UserUsedVo userUsed(OrderSubscribeDetailsBizDto orderSubscribeDetailsBizDto,
								CarDetailBizDto carDetailBizDto) {
		UserUsedVo used = new UserUsedVo();
		// 使用天数、使用里程数
		Integer usedDays = 0, usedMileage = 0;
		// 购买里程(基础里程+订阅里程+赠送里程+订阅里程（加购）)
		Integer payMileage = orderSubscribeDetailsBizDto.getBaseMileage()
				+ orderSubscribeDetailsBizDto.getPackageMileage() + orderSubscribeDetailsBizDto.getGiftMileage()
				+ orderSubscribeDetailsBizDto.getPurchaseMileage();
		if (OrderStatusConst.SUBSCRIBE_UNUSED_STATUS.contains(orderSubscribeDetailsBizDto.getOrderStatus())) {
			// 未用车订单，无使用情况
			return null;
		} else if (OrderStatusConst.SUBSCRIBE_USED_STATUS.contains(orderSubscribeDetailsBizDto.getOrderStatus())) {
			// 用车中订单，计算使用天数
			usedDays = (int) DateUtil.getDaysDiff(orderSubscribeDetailsBizDto.getLeaseInception(), LocalDate.now());
			// 查询订单车辆当前行驶里程
			Integer currentMileage = iovCarService.getCurrentMileage(carDetailBizDto.getVin());
			if (DateUtil.getDaysDiff(orderSubscribeDetailsBizDto.getLeaseExpire(), LocalDate.now()) > 0) {
				// 超期
				used.setIsInvalid(true);
				// 计算超期前超出的未结算里程（订单到期时里程-预警里程）
				Integer beyondMileage = orderSubscribeDetailsBizDto.getEndMileage()
						- orderSubscribeDetailsBizDto.getWarningMileage();
				beyondMileage = beyondMileage > 0 ? beyondMileage : 0;
				// 计算超期后超出的里程数(当前里程-订单到期时里程)
				beyondMileage += currentMileage - orderSubscribeDetailsBizDto.getEndMileage();
				// 已超期订单，使用里程为购买里程+超出的里程数
				usedMileage = payMileage + beyondMileage;
			} else {
				// 未超期
				used.setIsInvalid(false);
				// 计算使用里程(当前里程-订单开始时里程-已结算超里程数)
				usedMileage = currentMileage - orderSubscribeDetailsBizDto.getStartMileage();
				if (orderSubscribeDetailsBizDto.getBeyondMileage() != null) {
					usedMileage -= orderSubscribeDetailsBizDto.getBeyondMileage();
				}
			}
		} else {
			// 已还车订单, 计算使用天数
			usedDays = (int) DateUtil.getDaysDiff(orderSubscribeDetailsBizDto.getLeaseInception(),
					orderSubscribeDetailsBizDto.getLeaseExpire());
			// 已还车订单，使用里程为购买里程
			usedMileage = payMileage;
		}

		// 用车时长
		used.setTransporTime(orderSubscribeDetailsBizDto.getTransportTime());
		// 订单天数
		used.setOrderDays((int) DateUtil.getDaysDiff(orderSubscribeDetailsBizDto.getLeaseInception(),
				orderSubscribeDetailsBizDto.getLeaseExpire()));
		// 使用天数
		used.setUsedDays(usedDays);
		// 时长说明
		used.setDurationExplain("(超时收费标准" + OrderConst.DAY_UNIT_PRICE + "元/天)");
		// 截止日
		used.setLeaseExpire(orderSubscribeDetailsBizDto.getLeaseExpire());
		// 购买里程数
		used.setPayMileage(payMileage);
		// 使用里程数
		used.setUsedMileage(usedMileage);
		// 里程数说明
		used.setMileageExplain("(超出里程部分，30公里内将按" + OrderConst.MILEAGE_UNIT_PRICE + "元/公里收取费用)");

		return used;
	}


}
